var request = require('request'); 
class THttpUtils{
    static httpCall( aUrl , aMethod, aPs , aBody ){
        return new Promise((success , faild)=>{
            try{
                var callUrl = aUrl;
                if( aPs && aPs!=null && Object.keys(aPs)&& Object.keys(aPs).length>0 ){
                    callUrl += callUrl.indexOf("?")>0?"&":"?";
                    callUrl += "randtm="+Math.random();
                    Object.keys(aPs).forEach( p=>{
                        callUrl+="&"+p+"="+aPs[p];
                    })
                }

                var opts ={                                    
                    url: callUrl,
                    method: aMethod
                }

                if( aBody && aBody!=null ){
                    opts.body = aBody;
                }

                request( opts , ( err, resp , result)=>{
                    success({
                        err: err ,
                        resp:resp ,
                        result :result
                    })
                })
            }
            catch(Exce){
                console.log(Exce);
                success(null);
            }
        })
    }
    static writeDB( aUrl , dbName, tableName , tags , fields , timestampe){
        return new Promise((success , faild)=>{
            try{
                var ps={
                    db:dbName 
                };
                var tagDatas=[];
                Object.keys(tags).forEach( t=>{
                    tagDatas.push(t+"="+tags[t]);
                })
                var fieldDatas = [];
                Object.keys(fields).forEach(f=>{
                    fieldDatas.push(f+"="+fields[f]);
                })
                var body = tableName+","+tagDatas.join(",")+' '+fieldDatas.join(",")+" "+ timestampe;
                var url = aUrl+"/write";
                THttpUtils.httpCall( url , "POST" , ps , body).then(res=>{
                    success(res);
                })
            }
            catch(Exce){
                console.log(Exce);
                success(null);
            }
        })
    }
    static queryDB( aUrl , dbName, sql){
        return new Promise((success , faild)=>{
            try{
                var ps={
                    db:dbName ,
                    q: sql
                };
                var url = aUrl+"/query";
                THttpUtils.httpCall( url , "GET" , ps , body).then(res=>{
                    var r = JSON.parse(res.result).results;
                    success(r);
                })
            }
            catch(Exce){
                console.log(Exce);
                success(null);
            }
        })
    }
    static getTimestampe( strTime){
        var res = ( new Date()).getTime() * 1000 * 1000;
        try{
            res =  (new Date(Date.parse(strTime.replace(/-/g,"/")))) * 1000 * 1000
        }
        catch(er){
            console.log(er);
        }
        return res;
    }
}
class TGk{
    constructor(){
        this.config={
            db:{
                url:"http://127.0.0.1:30101" ,
                dbName:"gkdb_sd" ,
                realTable:"T_Real" 
            },
            tm:{
                cycleTm:5*60*1000 ,
                lastTm: 0
            }, 
            srcUrls:{
                real:"http://123.234.35.141:1008/ashx/dataManage/HCInterface.ashx?action=getNewData&datatype=minute" ,
                his:"http://123.234.35.141:1008/ashx/dataManage/HCInterface.ashx?action=getHistoryData&datatype=minute&startDate={startDt}&endDate={endDt}&mn={code}"
            } ,
            realFields:[
                "co" , "so2" , "no2" ,"pm25" , "pm10" , "tsp" ,  "o3" , "ta" , "ua" , "wd" , "ws" 
            ]
        }
    }
    //读取实时数据
    getPoints(){
        var me = this;
        return new Promise((success, faild)=>{
            var pts={};
            try{
                request.get( me.config.srcUrls.real , function(erget,resp){
                    try{
                        var content = JSON.parse(resp.body);
                        if( content.Result ){
                            var datas = content.realDatas;
                            var reals ={};
                            datas.forEach( item=>{
                                if( !reals[item.mn]){
                                    var pt = {
                                        mn: item.mn ,
                                        projectName: item.projectName ,
                                        deviceName: item.deviceName ,
                                        statusDev: item.statusDev ,
                                        deviceId: item.deviceId ,
                                    }
                                    pts[pt.mn]  = pt;
                                } 
                            })
                            success(pts);
                        }
                        else{
                            success(pts );
                        }
                    }
                    catch(eer){
                        console.log("-------------  input real faild ---------------");
                        console.log(eer);
                        success(pts );
                    }
                }) 
            }
            catch(er){
                console.log(er);
                success(pts );
            }
        })
    }
    //读取实时数据
    getRealDatas(){
        var me = this;
        return new Promise((success, faild)=>{
            try{
                request.get( me.config.srcUrls.real , function(erget,resp){
                    try{
                        var content = JSON.parse(resp.body);
                        if( content.Result ){
                            var datas = content.realDatas;
                            var reals ={};
                            datas.forEach( item=>{
                                if( !reals[item.mn]){
                                    reals[item.mn] ={
                                        mn: item.mn ,
                                        time:item.time 
                                    }
                                    me.config.realFields.forEach( field=>{
                                        reals[item.mn][field] = 0.0;
                                    })
                                }
                                var realItem = reals[item.mn];
                                me.config.realFields.forEach( field=>{
                                    var value = 0.0;
                                    if(item[field] !=null &&  item[field]>=0){
                                        value = 1.0 *  item[field] ;
                                        realItem[field] = value;
                                    }
                                })
                            })
                            success(reals);
                        }
                        else{
                            success( );
                        }
                    }
                    catch(eer){
                        console.log("-------------  input real faild ---------------");
                        console.log(eer);
                    }
                }) 
            }
            catch(er){
                console.log(er);
            }
        })
    }
    //读取历史数据
    getHisDatas( code , startTm , endTm ){
        var me = this;
        return new Promise((success, faild)=>{
            var hisDatas =[];
            try{
                var url = me.config.srcUrls.his;
                url = url.replace("{startDt}" , startTm);
                url = url.replace("{endDt}" , endTm);
                url = url.replace("{code}" , code);
                request.get( me.config.srcUrls.real , function(erget,resp){
                    try{
                        var content = JSON.parse(resp.body);
                        if( content.Result ){
                            var datas = content.realDatas;
                            datas.forEach( item=>{
                                var timestampe = THttpUtils.getTimestampe(item.time);
                                var tags ={
                                    mn: code
                                };
                                var fields = {};
                                me.config.realFields.forEach(f=>{
                                    if( item[f] !=null && item[f]>=0){
                                        fields[f] = item[f]*1.0;
                                    }
                                });
                                var dataStr = me.config.db.realTable+","+ tags.join(",")+ " "+ fields.join(",") +" "+ timestampe;
                                hisDatas.push(dataStr);
                            })
                            success(hisDatas);
                        }
                        else{
                            success( hisDatas );
                        }
                    }
                    catch(eer){
                        console.log("-------------  input his faild ---------------");
                        console.log(eer);
                        success( hisDatas);
                    }
                }) 
            }
            catch(er){
                console.log(er);
            }
        })
    }
    //读取实时数据
    inputRealDatas(){
        var me = this;
        return new Promise((success, faild)=>{
            try{
                me.getRealDatas().then( reals=>{
                    var items = Object.values(reals);
                    var impItem = function(){
                        if( items.length>0){
                            var item = items.shift();
                            var tags = {
                                mn: item.mn
                            };
                            var fields={};
                            me.config.realFields.forEach( f=>{
                                var value = item[f];
                                if( value!=null && value>=0){
                                    fields[f] = value;
                                }
                            })
                            var tm = THttpUtils.getTimestampe(item.time);
                            THttpUtils.writeDB( me.config.db.url , me.config.db.dbName, me.config.db.realTable , tags , fields , tm).then(_=>{
                                impItem();
                            })
                        }
                        else{
                            success();
                        }
                    }
                    impItem();
                })
            }
            catch(er){
                console.log(er);
            }
        })
    }
    //读取实时数据
    inputHisDatas(startTm , endTm){
        var me = this;
        return new Promise((success, faild)=>{
            try{
                me.getPoints().then(_pts=>{
                    var pts = Obj.values(_pts);
                    var items=[];
                    var loadHis = function(){
                        if( pts.length>0){
                            var pt = pts.shift();
                            var code = pt.mn;
                            me.getHisDatas( code , startTm , endTm).then(ptDatas=>{
                                try{
                                    while(ptDatas.length>0){
                                        var item = ptDatas.shift();
                                        items.push(item);
                                    }
                                }
                                catch(err){
                                    console.log(eer);
                                }
                                loadHis();
                            });
                        }
                        else{
                            var write2DB= function(){
                                if( items.length>0){
                                    var item = items.shift();
                                    var ps={
                                        db:me.config.db.dbName 
                                    };
                                    var url = aUrl+"/write";
                                    THttpUtils.httpCall( url , "POST" , ps , item).then(res=>{
                                        write2DB();
                                    })
                                }
                                else{
                                    success();
                                }


                            }
                            write2DB(); 
                        }
                    }
                    loadHis();
                })
            }
            catch(er){
                console.log(er);
            }
        })
    }
    startImport(){
        var me = this;
        try{
            var tm = me.config.tm.cycleTm ;
            tm = tm>0?tm:5* 60* 1000;
            me.inputRealDatas().then(_=>{
                console.log('input real.')
                setTimeout( _=>{
                    me.startImport();
                }, tm)
            })
        }
        catch(er){
            console.log(er);
        }
    }

}

var gk = new TGk();
gk.startImport()
